package com.jcfy.common.utils.oss;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.GetObjectRequest;
import com.jcfy.common.utils.DateUtils;
import com.jcfy.common.utils.IdUtils;
import com.jcfy.framework.config.AliyunOssConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 阿里对象存储
 *
 * @author jiangfeng
 * 使用前请修改 AliyunOss配置文件
 */
public class AliyunOss {

    private static final Logger logger = LoggerFactory.getLogger(AliyunOss.class);

    public static String accessKeyId = AliyunOssConfig.getAccessKeyId();

    public static String accessKeySecret = AliyunOssConfig.getAccessKeySecret();

    public static String endpoint = AliyunOssConfig.getEndpoint();

    public static String bucketName = AliyunOssConfig.getBucketName();

    // 不包含 gif，图片会进行压缩
    public static List<String> imgSuffix = Arrays.asList("jpg","jpeg","png","bmp");

    /**
     * TODO:	上传单个图片
     *
     * @param filePath
     * @return
     * @throws MalformedURLException
     * @throws IOException
     * @data: 2017年9月29日
     * @author: hushuai
     */
    public static String aliOssUpload(MultipartFile filePath) throws MalformedURLException, IOException {
        String aliOssSave = null;
        try {
            String savePath = creatSavePath(filePath.getOriginalFilename());
            //获取最后一个.的位置
            int lastIndexOf = savePath.lastIndexOf(".");
            //获取文件的后缀名 .jpg
            String suffix = savePath.substring(lastIndexOf);
            if (!imgSuffix.contains(suffix)){
//            if (savePath.contains(".gif")) {
                aliOssSave = aliOssSave(savePath, filePath.getInputStream());
            } else {
                InputStream inputStream = filePath.getInputStream();
                // 把图片读入到内存中
                BufferedImage bufImg = ImageIO.read(inputStream);
                // 压缩代码
                // 存储图片文件byte数组
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                // 防止图片变红
                BufferedImage newBufferedImage = new BufferedImage(bufImg.getWidth(), bufImg.getHeight(), BufferedImage.TYPE_INT_RGB);
                newBufferedImage.createGraphics().drawImage(bufImg, 0, 0, Color.WHITE, null);
                //先转成jpg格式来压缩,然后在通过OSS来修改成源文件本来的后缀格式
                ImageIO.write(newBufferedImage, "jpg", bos);
                //获取输出流
                inputStream = new ByteArrayInputStream(bos.toByteArray());

                aliOssSave = aliOssSave(savePath, inputStream);
            }
        } catch (Exception e) {
            logger.error("[文件上传][状态#异常][原因# ", e.getMessage() + "]", e);
        }
        return aliOssSave;
    }

    /**
     * TODO:	上传多个文件
     *
     * @param files
     * @return
     * @throws MalformedURLException
     * @throws IOException
     * @data: 2017年9月29日
     * @author: hushuai
     */
    public static List<String> aliOssUpload(MultipartFile[] files) throws MalformedURLException, IOException {
        List<String> ossPathList = new ArrayList<String>();
        try {
            for (MultipartFile string : files) {
                String savePath = creatSavePath(string.getOriginalFilename());
                String aliOssSave = null;
                if (savePath.contains(".gif")) {
                    aliOssSave = aliOssSave(savePath, string.getInputStream());
                } else {
                    InputStream inputStream = string.getInputStream();
                    // 把图片读入到内存中
                    BufferedImage bufImg = ImageIO.read(inputStream);
                    // 压缩代码
                    // 存储图片文件byte数组
                    ByteArrayOutputStream bos = new ByteArrayOutputStream();
                    // 防止图片变红
                    BufferedImage newBufferedImage = new BufferedImage(bufImg.getWidth(), bufImg.getHeight(), BufferedImage.TYPE_INT_RGB);
                    newBufferedImage.createGraphics().drawImage(bufImg, 0, 0, Color.WHITE, null);
                    //先转成jpg格式来压缩,然后在通过OSS来修改成源文件本来的后缀格式
                    ImageIO.write(newBufferedImage, "jpg", bos);
                    //获取输出流
                    inputStream = new ByteArrayInputStream(bos.toByteArray());

                    aliOssSave = aliOssSave(savePath, inputStream);
                }
                ossPathList.add(aliOssSave);
            }
        } catch (Exception e) {
            logger.error("[文件上传][状态#异常][原因# ", e.getMessage() + "]", e);
        }
        return ossPathList;
    }

    /**
     * TODO 上传文件(单个)
     *
     * @param filePath
     * @return
     * @throws MalformedURLException
     * @throws IOException
     * @data: 2019-03-27
     * @author: jiangfeng
     */
    public static String aliOssUploadFile(MultipartFile filePath) throws MalformedURLException, IOException {
        String aliOssSave = null;
        try {
            String savePath = creatSavePath(filePath.getOriginalFilename());
            aliOssSave = aliOssSave(savePath, filePath.getInputStream());
        } catch (Exception e) {
            logger.error("[文件上传][状态#异常][原因# ", e.getMessage() + "]", e);
        }
        return aliOssSave;
    }


    /**
     * 上传流文件
     *
     * @param fileName    要保存的文件名  文件名尽量保持唯一
     * @param inputStream 流
     * @return
     */
    public static String aliOssSave(String fileName, InputStream inputStream) {
        if (null != fileName && !"".equals(fileName) && null != inputStream) {
            //初始化
            OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
            ossClient.putObject(bucketName, fileName, inputStream);
            ossClient.shutdown();
            return "https://" + bucketName + "." + endpoint + "/" + fileName;
        } else {
            return "";
        }

    }

    /**
     * 上传网络流
     *
     * @param fileName 保存的文件名 文件名尽量保持唯一
     * @param url      网络文件地址
     * @return
     * @throws MalformedURLException
     * @throws IOException
     */
    public static String aliOssSave(String fileName, String url) throws MalformedURLException, IOException {
        if (null != fileName && !"".equals(fileName) && null != url && !"".equals(url)) {
            OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
            InputStream inputStream = new URL(url).openStream();
            ossClient.putObject(bucketName, fileName, inputStream);
            ossClient.shutdown();
            return "https://" + bucketName + "." + endpoint + "/" + fileName;
        } else {
            return "";
        }
    }

    /**
     * TODO 上传本地文件
     *
     * @param dir 本地文件目录
     * @return
     */
    public static String aliOssUploadLocal(String dir) {
        String aliOssSave = null;
        try {
            if (null != dir && !"".equals(dir)) {
                File file = new File(dir);
                InputStream inputStream = new FileInputStream(file);
                // 把图片读入到内存中
                BufferedImage bufImg = ImageIO.read(inputStream);
                // 压缩代码
                // 存储图片文件byte数组
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                // 防止图片变红
                BufferedImage newBufferedImage = new BufferedImage(bufImg.getWidth(), bufImg.getHeight(), BufferedImage.TYPE_INT_RGB);
                newBufferedImage.createGraphics().drawImage(bufImg, 0, 0, Color.WHITE, null);
                //先转成jpg格式来压缩,然后在通过OSS来修改成源文件本来的后缀格式
                ImageIO.write(newBufferedImage, "jpg", bos);
                //获取输出流
                inputStream = new ByteArrayInputStream(bos.toByteArray());

                String savePath = creatSavePath(file.getName());
                aliOssSave = aliOssSave(savePath, inputStream);
            }
        } catch (Exception e) {
            logger.error("[上传本地文件][状态#异常][原因# ", e.getMessage() + "]", e);
        }
        return aliOssSave;
    }


    /**
     * 上传本地文件
     *
     * @param fileName 保存的文件名 文件名尽量保持唯一
     * @param dir      文件目录
     * @return
     * @throws UnsupportedEncodingException
     * @throws ClientException
     * @throws OSSException
     */
    public static String aliOssSaveLocal(String fileName, String dir) throws OSSException, ClientException, UnsupportedEncodingException {
        if (null != fileName && !"".equals(fileName) && null != dir && !"".equals(dir)) {
            OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
            ossClient.putObject(bucketName, fileName, new File(dir));
            ossClient.shutdown();
            return "https://" + bucketName + "." + endpoint + "/" + fileName;
        } else {
            return "";
        }
    }

    /**
     * 下载文件
     *
     * @param fileName 要下载的文件名
     * @param local    保存本地文件路径
     */
    public static void downLoad(String fileName, String local) {
        if (null != fileName && !"".equals(fileName) && null != local && !"".equals(local)) {
            OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
            ossClient.getObject(new GetObjectRequest(bucketName, fileName), new File(local));
            ossClient.shutdown();
        }
    }

    public static String creatSavePath(String fileName) throws UnsupportedEncodingException {
        // 上传文件的扩展名
        String fileExt = fileName.substring(fileName.lastIndexOf("."));
        // 将原文件名转换成URLEncoder编码(防止中文乱码)，下载时使用
        String downloadFileName = URLEncoder.encode(fileName, "UTF-8");
        // 获取文件类型(设置响应头使用，可以控制文件的响应方式)
        //String contentType = getContentType(fileName);
        // 保存的文件名(使用随机生成的文件名，防止重名冲突)
        String saveFileName = IdUtils.fastSimpleUUID() + fileExt;
        // 获取当前日期
        String date = "guomei/" + DateUtils.datePath() + "/";
        return date + saveFileName;
    }


    /**
     * 通过文件名判断并获取OSS服务文件上传时文件的contentType
     *
     * @param fileName 文件名
     * @return 文件的contentType
     */
    public static final String getContentType(String fileName) {
        String fileExtension = fileName.substring(fileName.lastIndexOf(".") + 1);
        if ("bmp".equalsIgnoreCase(fileExtension))
            return "image/bmp";
        if ("gif".equalsIgnoreCase(fileExtension))
            return "image/gif";
        if ("jpeg".equalsIgnoreCase(fileExtension) || "jpg".equalsIgnoreCase(fileExtension)
                || "png".equalsIgnoreCase(fileExtension))
            return "image/jpeg";
        if ("html".equalsIgnoreCase(fileExtension))
            return "text/html";
        if ("txt".equalsIgnoreCase(fileExtension))
            return "text/plain";
        if ("vsd".equalsIgnoreCase(fileExtension))
            return "application/vnd.visio";
        if ("ppt".equalsIgnoreCase(fileExtension) || "pptx".equalsIgnoreCase(fileExtension))
            return "application/vnd.ms-powerpoint";
        if ("doc".equalsIgnoreCase(fileExtension) || "docx".equalsIgnoreCase(fileExtension))
            return "application/msword";
        if ("xml".equalsIgnoreCase(fileExtension))
            return "text/xml";
        return "text/html";
    }
}
